#pragma once

#include "Widgets/Widget.h"


#include "FileBrowserWidget.m.h"

class REditableTextWidget;
enum class ETextEditStopReason;
class RListWidget;
class RMouseWidget;
class RKeyboardWidget;

//browse file and directory
//designed for Linux
RCLASS()
class WHENGINE_API RFileBrowserWidget : public RWidget
{
    ROBJECT

public:

    struct SFavoriteDirectory
    {
        CString DisplayName;
        SPath Path;
    };


    RFileBrowserWidget();

    void ShowContent(
        const SPath& InitialDirectory,
        const TVector<CString>& AllowedFileExtensions= {}, //for example ".png" 
        bool OnlyShowDirectory=false,
        bool MultiSelectFile=false,
        const TVector<SFavoriteDirectory>& ExtraFavoriteDirectorys={}
    );

    void UpdateFilter(const TVector<CString>& AllowedFileExtensions);

    //callback when file selected or unselected
    TDelegate<void> OnFileSelectionChanged;

    TDelegate<void> OnDirectoryChanged;

    TVector<SPath> GetSelectedFile() const;

    TOptional<SPath> GetSelectedDirectory() const;

    SPath GetCurrentDirectory() const;
protected:
    TVector<SFavoriteDirectory> FavoriteDirectorys;
    TVector<CString> AllowedFileExtensions;
    bool OnlyShowDirectory;
    bool MultiSelectFile;

    TWeakObjectPtr<REditableTextWidget> EditablePath;
    TWeakObjectPtr<RListWidget> FavoriteDicrectoryList;
    TWeakObjectPtr<RListWidget> ContentList;

    TVector<SPath> History;

    TVector<SPath> SelectedFiles;
    TOptional<SPath> SelectedDirectory; 

    //index of History
    int CurrentDirectory;

    void OnDirectoryAccepted(ETextEditStopReason Reason,const CString& InText);
    bool OnBackButtonClicked(const SMouseButtonEvent&);
    bool OnForwardButtonClicked(const SMouseButtonEvent&);
    bool OnUpButtonClicked(const SMouseButtonEvent&);
    bool OnAddDirectoryButtonClicked(const SMouseButtonEvent&);
    bool OnRefreshButtonClicked(const SMouseButtonEvent&);

    //regenerate current directory Content
    void UpdateContentList();
    void UpdateFavoriteList();
    void UpdateEditablePathWidget();

    void ChangeDirectory(const SPath& NewDirectory);

    struct SContentListItemWidget
    {
        RWidgetPtr ItemWidget;
        TSharedObjectPtr<RMouseWidget> ItemMouse;
    };
    SContentListItemWidget CreateContentListItem(const SPath& Path,bool IsFile=false);
    void SelectItem(RWidgetPtr ItemWidget,bool ForceUnselectOthers=false);
    void UnselectItem(RWidgetPtr ItemWidget);

    TWeakObjectPtr<RKeyboardWidget> Keyboard;
    bool OnKeyboardInput(const SKeyboardEvent& InputEvent);

    //return true if succeed started
    bool StartEditSelectedItemText();

    //create a directory item under current directory
    RWidgetPtr CreateDirectoryItem(const SPath& DirectoryName);
};

